﻿//Copyright © 2012  Daniel Lopez

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;
namespace NASM_Develop_IDE
{

    static class NASMBuilder
    {
        internal static string NasmPath = "nasm.exe";

        public static string Compile(string arguments)
        {
            try
            {
                var startInfo = new ProcessStartInfo(NasmPath)
                {
                    Arguments = arguments,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                };

                Process p = Process.Start(startInfo);
                var output = p.StandardOutput.ReadToEnd();
                var error = p.StandardError.ReadToEnd();
                p.WaitForExit();

                if (output.Length != 0) return output;
                if (error.Length != 0) return error;

                // If no output or error just return a blank line
                return Environment.NewLine;
            }
            catch(Exception ex)
            {
                NasmIdeLogger.LogError(ex);
                return null;
            }
        }
        
        public static string BuildFromScript(string filename, string[] nasmSource, string[] objects, string output)
        {

            Runspace runspace = RunspaceFactory.CreateRunspace();
            
            runspace.Open();

            Pipeline pipeline = runspace.CreatePipeline();

         
           
            //create command with script path
            Command c = new Command(filename, false);
            c.Parameters.Add(new CommandParameter(null, nasmSource));
            c.Parameters.Add(new CommandParameter(null, objects));
            c.Parameters.Add(new CommandParameter(null, output));
            pipeline.Commands.Add(c);
            //create a collection to hold output of script
            Collection<PSObject> results = new Collection<PSObject>();
            try
            {
                // execute the script
                results = pipeline.Invoke();
            }
            catch (Exception ex)
            {
                results.Add(new PSObject((object)ex.Message));
            }
            runspace.Close();
            StringBuilder stringBuilder = new StringBuilder();
            //loopthru all the objects returned (each object will contain output text)
            foreach (PSObject obj in results)
            {
                if (obj != null)
                    stringBuilder.AppendLine(obj.ToString());
            }
            return stringBuilder.ToString();
        }
        public static bool Link(string arguments, out StringBuilder linkOutput)
        {
            try
            {
                linkOutput = new StringBuilder();
                ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
                startInfo.Arguments = "/C " + " gcc " + arguments;
                startInfo.RedirectStandardError = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                Process p = Process.Start(startInfo);
                string output = p.StandardOutput.ReadToEnd();
                string error = p.StandardError.ReadToEnd();
                p.WaitForExit();
                if (output.Length != 0)
                    linkOutput.Append(output);
                else if (error.Length != 0)
                    linkOutput.Append(error);
                else
                    linkOutput.Append("\n");
                return true;
            }
            catch
            {
                linkOutput = null;
                return false;
            }
        }
        public static bool Clean(string binPath)
        {
            if (string.IsNullOrWhiteSpace(binPath) || !Directory.Exists(binPath))
            {
                throw new ArgumentException(nameof(binPath), "Either path is null or it does not exist!");
            }

            try
            {
                var binInfo = new DirectoryInfo(binPath);
                foreach (var fileInfo in binInfo.GetFiles())
                {
                    try
                    {
                        fileInfo.Delete();
                    }
                    catch (Exception ex)
                    {
                        NasmIdeLogger.LogError(ex);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                NasmIdeLogger.LogError(ex);
                return false;
            }
        }
    }
}
